package com.uniview.controller;

import com.uniview.dto.RespDTO;
import com.uniview.event.RemoteRefreshRouteEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.bus.BusProperties;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.IntStream;

/**
 * @Author lux
 * @date: 2019/12/5
 * @desc:
 */
@RestController
@RequestMapping("/oauth2.0")
public class TestController {
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    ReactiveRedisTemplate reactiveRedisTemplate;
    @Autowired
    ApplicationEventPublisher publisher;
    @Autowired
    BusProperties busProperties;
    /**
     * @desc 发布远程事件监听
     */
    @RequestMapping(value = "/publish", method = RequestMethod.POST)
    public RespDTO publish(@RequestParam(value = "destination", required = false, defaultValue = "**") String destination) {
        //Since we extended RemoteApplicationEvent and we've configured the scanning of remote events using @RemoteApplicationEventScan, it will be treated as a bus event rather than just a regular ApplicationEvent published in the context.
        //因为我们在启动类上设置了@RemoteApplicationEventScan注解，所以通过context发送的时间将变成一个bus event总线事件，而不是在自身context中发布的一个ApplicationEvent
        publisher.publishEvent(new RemoteRefreshRouteEvent(this,busProperties.getId(),destination,"this is a testhsh"));
        return RespDTO.onSuc("publish success");
    }

    /**
     * @desc 线程安全测试
     */
    @RequestMapping("/test")
    public void testThread(){
        ExecutorService executorService = Executors.newFixedThreadPool(10000);
        IntStream.range(0, 10000).forEach(i ->
                executorService.execute(() -> redisTemplate.opsForValue().increment("thread:test", 1))
        );
    }

    /**
     * @desc 响应式redisTemplate测试
     *
     */
    @RequestMapping("/reactive")
    public RespDTO<Mono> testReactive(){
        Mono mono = reactiveRedisTemplate.opsForValue().set("reactive:test","1");
        mono.subscribe(System.out::println);
        return RespDTO.onSuc(mono);
    }

}
